#include "os_sys.h"
#if _WIN32
#include "lfqueue.h"
#include <synchapi.h>
#endif

#if _WIN32
int32_t OS_FSIZE(OS_FILE fp) {
  int32_t file_size = 0;
  int index = OS_FTELL(fp);
  OS_FSEEK(fp, 0, SEEK_END);
  file_size = OS_FTELL(fp);
  OS_FSEEK(fp, index, SEEK_SET);
  return file_size;
}
#endif

int SEM_PEND(rq_sem sem, uint32_t time) {
#if _WIN32
  int ret = 0;
  uint32_t wait_time = 0;
  do {
    ret = sem_trywait(&sem);
    if (ret == 0) {
      break;
    }
    if (time <= wait_time) {
      ret = -1;
      break;
    }
    Sleep(10);
    wait_time += 10;
  } while (1);
  return ret;
#else
  return Liot_SemaphoreAcquire(sem, time);
#endif
}

OS_MSGQUE MSG_QUEUE_CREATE(uint32_t count, uint32_t item_size) {
#if _WIN32
  OS_MSGQUE q = NULL;
  q = malloc(sizeof(MSG_QUEUE_t));
  if (!q) {
    return NULL;
  }
  q->data = malloc(count * item_size);
  if (!q->data) {
    free(q);
    return NULL;
  }
  q->item_size = item_size;
  if (0 != lfqueue_init(&q->queue)) {
    free(q->data);
    free(q);
    return NULL;
  }
  return q;
#else
  return xQueueCreate(count, item_size);
#endif
}

void MSG_QUEUE_DESTROY(OS_MSGQUE q) {
#if _WIN32
  if (q) {
    if (q->data) {
      free(q->data);
    }
    lfqueue_destroy(&q->queue);
    free(q);
  }
#else
  return vQueueDelete(q);
#endif
}

MSG_RET MSG_QUEUE_SEND(OS_MSGQUE q, const void *item, uint32_t wait_ticks) {
#if _WIN32
  int ret = 0;
  uint8_t *new_item = NULL;
  if (!q) {
    return -1;
  }
  new_item = malloc(q->item_size);
  if (!new_item) {
    return -1;
  }
  memcpy(new_item, item, q->item_size);
  ret = lfqueue_enq(&q->queue, new_item);
  if (ret != 0) {
    free(new_item);
  }
  return ret;
#else
  return xQueueSend(q, item, wait_ticks);
#endif
}

MSG_RET MSG_QUEUE_RECV(OS_MSGQUE q, void *item, uint32_t wait_ticks) {
#if _WIN32
  uint8_t *get_item = NULL;
  uint32_t get_time = 0;
  int ret = -1;
  if ((!q) || (!item)) {
    return -1;
  }
  do {
    get_item = lfqueue_deq(&q->queue);
    if (get_item) {
      ret = 0;
      break;
    }
    Sleep(10);
    get_time += 10;
  } while (get_time < wait_ticks);

  if (ret == 0) {
    memcpy(item, get_item, q->item_size);
    free(get_item);
  }
  return ret;
#else
  return xQueueReceive(q, item, wait_ticks);
#endif
}
